<template>
  <div class="monitor-box">
    <div class="left-box">
      <div class="control-box">
        <div class="search-box box-shadow">
          <a-form>
            <a-form-item label="标段">
              <a-select
                v-model:value="cellQueryFormState.sections[0].sectionId"
              >
                <a-select-option
                  v-for="section in sections"
                  :key="section.sectionId"
                  :value="section.sectionId"
                >
                  {{ section.sectionName }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="仅显示当日施工单元">
              <a-switch
                :defaultChecked="cellQueryFormState.workToday == 1"
                @change="
                  () => {
                    cellQueryFormState.workToday =
                      cellQueryFormState.workToday == 1 ? undefined : 1
                  }
                "
              />
            </a-form-item>
            <a-form-item label="单元状态">
              <a-select v-model:value="cellQueryFormState.status">
                <a-select-option
                  v-for="cellStatus in cellStatusDict.dict2"
                  :key="cellStatus.statusCode"
                  :value="cellStatus.statusCode"
                >
                  {{ cellStatus.statusName }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="单元名称">
              <a-input v-model:value="cellQueryFormState.cellName"></a-input>
            </a-form-item>
            <a-form-item>
              <a-button @click="getCellBaseInfoList" type="primary"
                >查询</a-button
              >
            </a-form-item>
          </a-form>
        </div>
        <div class="map-control box-shadow">
          <a-checkbox-group
            v-model:value="baseControl"
            @change="clickMapControl"
          >
            <span class="map-control-title">基础数据</span>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="border">单元边界</a-checkbox>
              </a-col>
            </a-row>
            <span class="map-control-title">强夯数据</span>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="design_1">一遍设计点</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox value="design_2">二遍设计点</a-checkbox>
              </a-col>
            </a-row>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="design_work_1">一遍施工点</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox value="design_work_2">二遍施工点</a-checkbox>
              </a-col>
            </a-row>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="fact_11">满夯施工点</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox value="real_tamp">实时数据</a-checkbox>
              </a-col>
            </a-row>
          </a-checkbox-group>
        </div>
      </div>
      <div class="cell-table-box box-shadow">
        <div class="table-box-header">
          单元列表
        </div>
        <div class="table-box-center">
          <a-table
            :scroll="{ y: setHeight('.table-box-center', 125) + 'px' }"
            :data-source="cellBaseInfoList.cellInfo"
            :rowKey="record => record.cellId"
            @change="getCellBaseInfoList"
            :pagination="{
              current: cellBaseInfoList.startPage,
              total: cellBaseInfoList.totalCount,
              pageSize: cellBaseInfoList.everyPage,
              showLessItems: true
            }"
          >
            <a-table-column
              title="归属标段"
              data-index="sectionName"
            ></a-table-column>
            <a-table-column
              title="单元名称"
              data-index="cellName"
            ></a-table-column>
            <a-table-column title="工艺类型" data-index="kind" width="80px">
              <template #default="{text}">
                <div>{{ kindDict.getNameByCode(text) }}</div>
              </template>
            </a-table-column>
            <a-table-column title="操作" data-index="cellId" width="50px">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="handleCell(record)">
                    <EditOutlined />
                  </div>
                </div>
              </template>
            </a-table-column>
            <a-table-column title="启停" data-index="cellStatus" width="50px">
              <template #default="{text,record}">
                <a-switch
                  :defaultChecked="text != 0"
                  @change="setCellStatus(record)"
                />
              </template>
            </a-table-column>
          </a-table>
        </div>
      </div>
    </div>
    <div class="right-box">
      <div class="base-info-box box-shadow">
        <a-descriptions :column="4">
          <a-descriptions-item label="单元名称" :span="1">
            {{ inCellBaseInfo ? inCellBaseInfo.cellName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="创建时间" :span="1">
            {{ inCellBaseInfo ? inCellBaseInfo.gtmCreateTime : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="工艺类型" :span="1">
            {{
              inCellBaseInfo
                ? kindDict.getNameByCode(inCellBaseInfo.kind)
                : '--'
            }}
          </a-descriptions-item>
          <a-descriptions-item label="归属标段" :span="1">
            {{ inCellBaseInfo ? inCellBaseInfo.sectionName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="区域面积" :span="1">
            {{ inCellBaseInfo ? inCellBaseInfo.area : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="创建账号" :span="1">
            {{ inCellBaseInfo ? inCellBaseInfo.userName : '--' }}
          </a-descriptions-item>
            <!-- 三检 -->
          <a-descriptions-item label="三检状态" :span="1">
            {{ tpiStatue ? tpiStatue : '--' }}
          </a-descriptions-item>
        </a-descriptions>
      </div>
      <div class="map-box box-shadow">
        <div class="map-event-control">
          <div
            @click="clickMapEvent(1)"
            :class="{
              'map-control-button': true,
              'map-control-active': tampPointInfo.type == 1
            }"
          >
            一遍点夯
          </div>
          <div
            @click="clickMapEvent(2)"
            :class="{
              'map-control-button': true,
              'map-control-active': tampPointInfo.type == 2
            }"
          >
            二遍点夯
          </div>
          <div
            @click="clickMapEvent(3)"
            :class="{
              'map-control-button': true,
              'map-control-active': tampPointInfo.type == 3
            }"
          >
            满夯
          </div>
        </div>
        <div
          class="point-info point-info-1"
          v-show="tampPointInfo.show && tampPointInfo.type != 3"
        >
          <div class="point-header">
            <span v-if="tampPointInfo.type == 1">
              一遍点夯
            </span>
            <span v-else-if="tampPointInfo.type == 2">
              二遍点夯
            </span>
            <span v-else></span>
            <CloseOutlined @click="tampPointInfo.show = false" />
          </div>
          <div class="point-content">
            <div class="left">
              <div class="left-info-box">
                <a-row>
                  <a-col :span="10">单元名称</a-col>
                  <a-col :span="14">{{ tampPointInfo.cellName }}</a-col>
                </a-row>
                <a-row>
                  <a-col :span="10">P坐标</a-col>
                  <a-col :span="14">{{ tampPointInfo.a }}</a-col>
                </a-row>
                <a-row>
                  <a-col :span="10">H坐标</a-col>
                  <a-col :span="14">{{ tampPointInfo.b }}</a-col>
                </a-row>
                <a-row>
                  <a-col :span="10">设计击数</a-col>
                  <a-col :span="14">{{ tampPointInfo.timesDesign }}</a-col>
                </a-row>
                <a-row>
                  <a-col :span="10">实际击数</a-col>
                  <a-col :span="14">{{ tampPointInfo.timesBuild }}</a-col>
                </a-row>
                <a-row>
                  <a-col :span="10">施工机械</a-col>
                  <a-col :span="14">{{ tampPointInfo.deviceName }}</a-col>
                </a-row>
              </div>
            </div>
            <div class="right">
              <a-table
                :scroll="{ y: '160px' }"
                :data-source="tampPointInfo.realData"
                :rowKey="record => record.gtmTime"
                :pagination="false"
              >
                <a-table-column title="时间" data-index="gtmTime" />
                <a-table-column
                  title="夯击能"
                  width="65px"
                  data-index="compactionEnergy"
                />
                <a-table-column
                  title="落距"
                  width="65px"
                  data-index="distance"
                />
              </a-table>
            </div>
          </div>
        </div>
        <div
          class="point-info point-info-2"
          v-show="tampPointInfo.show && tampPointInfo.type == 3"
        >
          <div class="point-header">
            <span>
              满夯
            </span>
            <CloseOutlined @click="tampPointInfo.show = false" />
          </div>
          <div class="point-content">
            <div class="info">
              <a-row>
                <a-col :span="10">单元名称</a-col>
                <a-col :span="14">{{ tampPointInfo.cellName }}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">P坐标</a-col>
                <a-col :span="14">{{ tampPointInfo.a }}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">H坐标</a-col>
                <a-col :span="14">{{ tampPointInfo.b }}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">实际击数</a-col>
                <a-col :span="14">{{
                  tampPointInfo.timesBuild < 0 ? 0 : tampPointInfo.timesBuild
                }}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">施工机械</a-col>
                <a-col :span="14">{{ tampPointInfo.deviceName }}</a-col>
              </a-row>
            </div>
          </div>
        </div>
        <div
          @click="openExAreaModal(inCellBaseInfo ? inCellBaseInfo.cellId : 0)"
          class="ex-area-btn"
        />
        <div @click="workListInfo.showModal = true" class="work-list-btn" />
        <!-- 三检按钮 -->
<!--        <a-popover>-->
<!--          <template #content>-->
<!--            <span>三检</span>-->
<!--          </template>-->
<!--          <div-->
<!--            class="tpi-list-btn"-->
<!--            @click="openTpiModal(inCellBaseInfo ? inCellBaseInfo.cellId : 0)"-->
<!--          />-->
<!--        </a-popover>-->
        <div class="tamp-legend">
          <div>
            <div class="legend">
              <div style="background: #F30105"></div>
            </div>
            <div class="legend-title">未开始</div>
          </div>
          <div>
            <div class="legend">
              <div style="background: #0100EF"></div>
            </div>
            <div class="legend-title">未完成</div>
          </div>
          <div>
            <div class="legend">
              <div style="background: #00F100"></div>
            </div>
            <div class="legend-title">已完成</div>
          </div>
        </div>
        <div id="mapboxgl-box"></div>
        <div class="draw-save" v-if=isDrawSave>
          <a-button type="default" shape="square" @click="saveDrawArea" size="middle">
            <template #icon>
              <CheckOutlined/>
            </template>
          </a-button>
        </div>
      </div>
    </div>
  </div>
  <SModal
    title="工作设备列表"
    width="480"
    :is-show="workListInfo.showModal"
    @closed="() => (workListInfo.showModal = false)"
  >
    <div class="smodal-box smodal-to-cell">
      <a-table
        :scroll="{ y: `205px` }"
        :data-source="workListInfo.workList"
        :rowKey="record => record.deviceId"
        @change="getToNextCellDevice"
        :pagination="false"
      >
        <a-table-column title="机械编号" data-index="deviceSn"></a-table-column>
        <a-table-column
          title="机械名称"
          data-index="deviceName"
        ></a-table-column>
        <a-table-column title="机械类型" data-index="deviceKind">
          <template #default="{text}">
            <div>{{ deviceTypeDict.getNameByCode(text) }}</div>
          </template>
        </a-table-column>
      </a-table>
    </div>
  </SModal>
  <SModal
      title="排除区域"
      width="1000"
      height="362"
      :is-show="showExModal"
      @closed="() => {showExModal = false}">
    <div class="ex-area-modal">
      <div class="ex-table-box">
        <a-table
            :scroll="{ y: '180px' }"
            :data-source="exAreaList"
            :rowKey="record => record.serial"
            :pagination="false">
          <a-table-column title="序号" data-index="serial" width="60px"/>
          <a-table-column title="排除时间" data-index="gtmCreateTime"/>
          <a-table-column title="操作人员" data-index="userName" width="100px"/>
          <a-table-column title="排除区域名称" data-index="excludedName" width="160px">
            <template #default="{text,record}">
              <div style="padding: 0 8px">
                <a-input
                    v-model:value="record.excludedName"
                    v-if="record.excludedId < 0"/>
                <span v-else>{{ text }}</span>
              </div>
            </template>
          </a-table-column>
          <a-table-column title="排除原因" data-index="reason">
            <template #default="{text,record}">
              <div style="padding: 0 8px">
                <a-input
                    v-model:value="record.reason"
                    v-if="record.excludedId < 0"/>
                <span v-else>{{ text }}</span>
              </div>
            </template>
          </a-table-column>
          <a-table-column title="面积" data-index="area"/>
          <a-table-column title="排除区域范围" data-index="excludedId" width="140px">
            <template #default="{text,record}">
              <a-button @click="openFileModal(record)" :disabled="record.excludedId > 0"
                        type="primary" ghost
                        style="margin-right: 10px">导入</a-button>
              <a-button @click="drawTheBorder(record)" :disabled="record.excludedId > 0"
                        type="primary" ghost>绘制</a-button>
            </template>
          </a-table-column>
          <a-table-column title="坐标" width="60px">
            <template #default="{text,record, index}">
              <!--              {{ text }}-->
              <div class="icon-box" @click="openCoordinateModel(record)">
                <BorderOuterOutlined />
              </div>
            </template>
          </a-table-column>
          <a-table-column title="操作" data-index="excludedId" width="60px">
            <template #default="{text,record,index}">
              <div
                  class="table-icon-box"
                  style="padding: 0 5px; font-size: 16px">
                <div v-if="text <= 0" @click="saveExArea(record)">
                  <SaveOutlined />
                </div>
                <div v-if="text <= 0" @click="delExArea(record, index)">
                  <DeleteOutlined />
                </div>
                <div v-if="text > 0" @click="delExArea(record, index)">
                  <DeleteOutlined />
                </div>
              </div>
            </template>
          </a-table-column>
        </a-table>
      </div>
      <div class="ex-area-btn-box">
        <a-button @click="addExArea" type="primary">新增</a-button>
      </div>
    </div>
    <input
        id="read-ex-area-input"
        @change="readBorderFile"
        accept=".txt"
        type="file"
        style="position:absolute;width:0;height:0;opacity:0"/>
  </SModal>
  <SModal
      title="排除区域坐标"
      :width="372"
      :height="350"
      :isShow="showCoordinateModal"
      @closed="() => {showCoordinateModal = false}">
    <div class="coor-table-box">
      <!--      <span>{{ borderList }}</span>-->
      <a-table
          :data-source="borderList"
          :scroll="{y: '180px' }"
          :pagination="false">
        <a-table-column title="P坐标" data-index="first">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
        <a-table-column title="H坐标" data-index="second">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
      </a-table>
      <div class="down-btn-box">
        <a-button @click="downloadBorderFile()" type="primary">下载</a-button>
      </div>
    </div>
  </SModal>
  <!-- 三检 -->
  <tpiModal
    :is-show="tpiListInfo.showModal"
    ref="TpiModalInit"
    @closed="() => (tpiListInfo.showModal = false)"
  ></tpiModal>
</template>

<script lang="ts">
import { useStore } from 'vuex'
import {
  defineComponent,
  reactive,
  ref,
  toRefs,
  onMounted,
  onBeforeUnmount
} from 'vue'
import { setHeight } from '@/utils/tableUtils'
import { cellBaseInfo } from '@/hooks/cell/index'
import kindDict from '@/dicts/kindDict'
import cellStatusDict from '@/dicts/cellStatusDict'
import mapboxgl, { AnyLayer, LngLat, Marker, Sources } from 'mapbox-gl'
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
import { TableToExcel } from "@/utils/tyutils/index"
import {
  EditOutlined,
  SaveOutlined,
  DeleteOutlined,
  CloseOutlined,
  CheckOutlined,
  BorderOuterOutlined
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import axios from 'axios'
import qs from 'qs'
import redLine from '@/assets/data/redLine.ts'
import 'mapbox-gl/dist/mapbox-gl.css'
import { MqttOptions, MqttService } from '@/utils/mqttService'
import config from '@/config/index'
import SModal from '@/components/SModal/index.vue'
import deviceTypeDict from '@/dicts/deviceTypeDict'
import moment from 'moment'

import lodash from 'lodash'
//三检
import tpiModal from '@/components/SModal/TpiModal.vue'
interface MapLayerRequestInfo {
  craft: string | null
  cellId: number | null
  type: string | null
}
class TampPointInfo {
  cellId = -1
  cellName = ''
  pointName = ''
  latitude = <any>undefined
  longitude = <any>undefined
  x = undefined
  y = undefined
  a = <any>undefined
  b = <any>undefined
  timesBuild = <any>undefined
  timesDesign = <any>undefined
  realData = new Array<any>()
  type = <any>undefined
  deviceName = <any>undefined
  show = false
}
interface MapDeviceInfo {
  deviceId: number
  deviceInfo: any
  deviceMarker: Marker
}

export default defineComponent({
  setup() {
    const store = useStore()
    const userName = ref(
      JSON.parse(JSON.stringify(store.getters['userinfo/getUserInfo'])).username
    )
    const sections = ref(
      JSON.parse(JSON.stringify(store.getters['userinfo/getUserSection']))
    )
    const {
      cellQueryFormRef,
      cellQueryFormState,
      cellBaseInfoList,
      inCellBaseInfo,
      getCellBaseInfoList,
      setCellStatus,
      getCellBaseInfo
    } = cellBaseInfo()
    cellQueryFormState.value.sections[0].kind = [2]
    const workListInfo = ref({
      showModal: false,
      workList: new Array<any>()
    })
    const mapControl = reactive({
      baseControl: new Array<string>(),
      tampPointInfo: new TampPointInfo()
    })
    // 三检
    const TpiModalInit = ref()
    const tpiListInfo = ref({
      showModal: false,
      tpiList: new Array<any>()
    })
     const tpiStatue = ref()
    const exAreaInfo = reactive({
      uploadFileRecord: <any>null,
      showExModal: false,
      exAreaList: new Array<any>()
    })
    let isDrawSave = ref(false)
    // 排除区域坐标点
    const coordinateList = reactive({
      borderList: new Array<any>()
    })
    const showCoordinateModal = ref(false)
    // 排除区域显示序号
    const exAreaSerial = reactive({
      data: {
        type: 'FeatureCollection',
        features: new Array<any>()
      }
    })

    const realMapInfo = reactive({
      deviceList: new Array<MapDeviceInfo>(), // 设备信息列表(主要用于marker)
      realSourceName: 'real_tamp',
      realSource: {
        // 实时施工数据源列表
        type: 'FeatureCollection',
        features: new Array<any>()
      },
      realLayerName: 'real_tamp', // 实时施工图层列表
      subscribeList: new Array<string>() // 订阅设备列表
    })
    // 看板跳转
    const zoneId:any = ref(null)
    const zoneKind:any = ref(null)

    let maps: any
    let draw: any
    let drawData: any

    //三检
    const getCellTpiStatue = (cellId: number) => {
      const userinfo = store.getters['userinfo/getUserInfo']
      if (userinfo) {
        const url =
          config.cityUrlPath + '/detection/work-unit/' + cellId + '/status'
        axios.get(url).then((res: any) => {
          if (res.success) {
            if (res.data.length > 0) {
              tpiStatue.value = res.data[0].status
            }
          }
        })
      }
    }
    // 三检状态
    const getAreaStatus = (cellId: number) => {
      const userinfo = store.getters['userinfo/getUserInfo']
      if (userinfo) {
        const url = config.cityUrlPath + '/detectionTest/detection/getAreaStatusbySysID?id=' + cellId
        axios.get(url).then((res: any) => {
          if (res.code == 0) {
            if (res.data == -1) {
              tpiStatue.value = '待检测'
            } else if (res.data == 0) {
              tpiStatue.value = '不合格'
            } else if (res.data == 1) {
              tpiStatue.value = '合格'
            }
          }
        })
      }
    }
    // 初始化地图
    const initMap = () => {
      mapboxgl.accessToken = config.map.accessToken
      let mapSource: Sources = {
        google: {
          type: 'raster',
          tiles: [
            config.map.baseLayer1URL,
            config.map.baseLayer2URL,
            config.map.baseLayer3URL
          ],
          tileSize: 256
        }
      }
      let layers: AnyLayer[] = [
        {
          id: 'google-tiles1',
          type: 'raster',
          source: 'google'
        }
      ]
      maps = {
        map: new mapboxgl.Map({
          container: 'mapboxgl-box',
          style: {
            version: 8,
            sources: mapSource,
            layers: layers,
            glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
          },
          minZoom: 5,
          maxZoom: 20,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }

      maps.map.on('load', () => {
        if (zoneId.value == null || zoneKind.value == null) {
          maps.map.addLayer({
            id: 'air',
            type: 'raster',
            source: {
              type: 'raster',
              tiles: [config.map.airUrl]
            }
          })
          maps.map.addSource('redLineSource', { type: 'geojson', data: redLine })
          maps.map.addLayer({
            id: 'redLineLayer',
            type: 'line',
            source: 'redLineSource',
            layout: {},
            paint: {
              'line-color': '#ff0000',
              'line-width': 2,
              'line-opacity': 1
            }
          })
        }
      })

      maps.map.on('click', (e: any) => {
        //三检
        if (tpiListInfo.value.showModal) {
          //等于true获得坐标显示在弹窗
          var lat = e.lngLat.lat
          var lng = e.lngLat.lng
          transWGS84ToLocal(lat, lng).then((res2: any) => {
            if (res2.data) {
              TpiModalInit.value.setSelAB(
                res2.data.x.toFixed(2),
                res2.data.y.toFixed(2)
              )
            } else {
              TpiModalInit.value.setSelAB('', '')
            }
          })
        }
        //end
        let type = mapControl.tampPointInfo.type
        if (type == 1 || type == 2) {
          getDotPoint(e.lngLat.lat, e.lngLat.lng).then((res: any) => {
            mapControl.tampPointInfo = new TampPointInfo()
            mapControl.tampPointInfo.type = type
            mapControl.tampPointInfo.cellName = inCellBaseInfo.value.cellName
            if (res.data != null) {
              Object.assign(mapControl.tampPointInfo, res.data)
              transWGS84ToLocal(
                mapControl.tampPointInfo.latitude,
                mapControl.tampPointInfo.longitude
              ).then((res2: any) => {
                if (res2.data) {
                  mapControl.tampPointInfo.a = res2.data.x.toFixed(2)
                  mapControl.tampPointInfo.b = res2.data.y.toFixed(2)
                  mapControl.tampPointInfo.show = true
                } else {
                  mapControl.tampPointInfo.show = false
                }
              })
            } else {
              mapControl.tampPointInfo.show = false
            }
          })
        } else if (type == 3) {
          getFullPoint(e.lngLat.lat, e.lngLat.lng).then((res: any) => {
            mapControl.tampPointInfo = new TampPointInfo()
            mapControl.tampPointInfo.type = type
            mapControl.tampPointInfo.cellName = inCellBaseInfo.value.cellName
            if (res.data != null) {
              mapControl.tampPointInfo.latitude = parseFloat(
                res.data.lat
              ).toFixed(6)
              mapControl.tampPointInfo.longitude = parseFloat(
                res.data.lng
              ).toFixed(6)
              mapControl.tampPointInfo.timesBuild = res.data.workTimes
              mapControl.tampPointInfo.deviceName = res.data.deviceName
              transWGS84ToLocal(
                mapControl.tampPointInfo.latitude,
                mapControl.tampPointInfo.longitude
              ).then((res2: any) => {
                if (res2.data) {
                  mapControl.tampPointInfo.a = res2.data.x.toFixed(2)
                  mapControl.tampPointInfo.b = res2.data.y.toFixed(2)
                  mapControl.tampPointInfo.show = true
                } else {
                  mapControl.tampPointInfo.show = false
                }
              })
            } else {
              mapControl.tampPointInfo.show = false
            }
          })
        }
      })
    }
    //自定义绘图工具
    const initDraw = () => {
      draw = new MapboxDraw({
        displayControlsDefault: false,
        controls: {
          polygon: true,
          trash: true
        },
        defaultMode: 'draw_polygon'
      })
      maps.map.addControl(draw, "top-left")
      maps.map.on('draw.create', () => {
        drawData = draw.getAll();
      })
      maps.map.on('draw.delete', () => {
        drawData = draw.getAll();
      })
      maps.map.on('draw.update', () => {
        drawData = draw.getAll();
      })
      //添加
      maps.map.on('draw.modechange', () => {
        drawData = draw.getAll();
        if (draw.getMode() == 'draw_polygon') {
          let pids: any[] = []
          // ID of the added template empty feature
          const lid = drawData.features[drawData.features.length - 1].id
          drawData.features.forEach((f: any) => {
            if (f.geometry.type === 'Polygon' && f.id !== lid) {
              pids.push(f.id)
            }
          })
          draw.delete(pids)
        }
      })
    }
    // 添加图层
    const addLayer = (
      layerInfo: MapLayerRequestInfo,
      callback: Function | null = null
    ) => {
      if (!maps.map) return
      maps.map.addLayer({
        id: `${layerInfo.type}`,
        type: 'raster',
        source: `${layerInfo.type}`,
        paint: {
          'raster-opacity': 1 //图层显示透明度
        }
      })
      maps.LayerList.add(`${layerInfo.type}`)
    }
    // 添加数据源
    const addSource = (
      layerInfo: MapLayerRequestInfo,
      callback: Function | null = null
    ) => {
      if (!maps.map) return
      maps.map.addSource(`${layerInfo.type}`, {
        type: 'raster',
        scheme: 'tms',
        tiles: [
           `${config.map.geoServer}${layerInfo.craft}%3A${layerInfo.cellId}_${layerInfo.type}@EPSG%3A900913@png/{z}/{x}/{y}.png`
        ],
        tileSize: 256
      })
      maps.sourceList.add(`${layerInfo.type}`)
    }
    // 移动地图视角
    const mapToCell = (cellCenter: LngLat) => {
      if (!maps.map) return
      maps.map.jumpTo({ center: cellCenter })
    }
    // 获取施工单元中正在工作设备列表
    const getCellWorkMachineryByCellId = (cell: any) => {
      return new Promise((resolve, reject) => {
        let data = {
          cellId: cell.cellId,
          kind: cell.kind
        }
        axios
          .post('/common/findCellWorkMachineryByCellId', data)
          .then((res: any) => {
            resolve(res)
          })
          .catch((err: any) => {
            reject(err)
          })
      })
    }
    // 列表中选择仓面
    const handleCell = (cell: any) => {
      removeDraw()
      clearSerial()
      let f1 = getCellBaseInfo(cell)
      let f2 = getCellWorkMachineryByCellId(cell)
      Promise.all([f1, f2]).then((res: any) => {
        // 1.持久化数据
        // 清除旧图层&数据源
        maps.LayerList.forEach((item: any) => {
          if (maps.map.getLayer(item)) {
            maps.map.removeLayer(item)
            maps.LayerList.delete(item)
          }
        })
        maps.sourceList.forEach((item: any) => {
          if (maps.map.getSource(item)) maps.map.removeSource(item)
        })
        // 添加默认图层
        let layerInfo: MapLayerRequestInfo = {
          cellId: inCellBaseInfo.value.cellId,
          craft: 'HaErBin-QH',
          type: 'border'
        }
        addSource(layerInfo)
        addLayer(layerInfo)

        // 2.实时数据
        // 先清除旧的实时显示相关的数据,图层,marker
        realMapInfo.deviceList.forEach((item: any) => {
          item.deviceMarker.remove()
        })
        realMapInfo.deviceList = new Array<MapDeviceInfo>()
        MqttService.unsubscribe(realMapInfo.subscribeList)
        realMapInfo.subscribeList = new Array<string>()
        realMapInfo.realSource.features = new Array<any>()
        if (maps.map.getLayer(realMapInfo.realLayerName))
          maps.map.removeLayer(realMapInfo.realLayerName)
        if (maps.map.getSource(realMapInfo.realSourceName))
          maps.map.removeSource(realMapInfo.realSourceName)

        // 订阅新选定仓面的设备数据
        workListInfo.value.workList = res[1].data
        res[1].data.forEach((item: any) => {
          let el = document.createElement('div')
          el.className = 'device-tamp'
          el.innerText = `${item.deviceName}`

          realMapInfo.deviceList.push({
            deviceId: item.deviceId,
            deviceInfo: item,
            deviceMarker: new mapboxgl.Marker(el)
              .setLngLat([0, 0])
              .setOffset(new mapboxgl.Point(86, -16))
              .addTo(maps.map)
          })
          MqttService.subscribe(
            `${config.craft.tamp.mqtt.topic}${item.deviceSn}`
          )
        })

        // 3.操作界面
        mapControl.baseControl = ['border', 'real_tamp']
        // 跳转位置
        if (res[0].data.centLat && res[0].data.centLon) {
          maps.map.setZoom(17)
          let cellCenter = new mapboxgl.LngLat(
            res[0].data.centLon,
            res[0].data.centLat
          )
          mapToCell(cellCenter)
        }
      })
      // 三检
      // getCellTpiStatue(cell.cellId)
      // 新三检
      getAreaStatus(cell.cellId)
      getAllPoint(cell.cellId)
    }
    const clickMapControl = (res: any) => {
      if (!inCellBaseInfo.value) {
        message.info('请先选择单元后再进行操作')
        return
      }
      let diffList = res
        .concat(Array.from(maps.LayerList))
        .filter((cur: any, i: any, arr: any) => {
          return arr.indexOf(cur) === arr.lastIndexOf(cur)
        })
      diffList.forEach((item: any) => {
        let layerInfo: MapLayerRequestInfo = {
          cellId: inCellBaseInfo.value.cellId,
          craft: 'HaErBin-QH',
          type: item
        }
        if (layerInfo.type != 'real_tamp') {
          let layer = maps.map.getLayer(`${layerInfo.type}`)
          let source = maps.map.getSource(`${layerInfo.type}`)
          if (!layer && !source) {
            // 增加图层及数据源
            addSource(layerInfo)
            addLayer(layerInfo)
          } else if (layer && source) {
            // 移除图层
            maps.map.removeLayer(`${layerInfo.type}`)
            maps.LayerList.delete(`${layerInfo.type}`)
          } else if (!layer && source) {
            // 增加图层
            addLayer(layerInfo)
          }
        }
      })
      let realTampIndex = diffList.indexOf('real_tamp')
      let realLayer = maps.map.getLayer('real_tamp')
      if (!maps.map.getSource(realMapInfo.realSourceName))
        maps.map.addSource(realMapInfo.realSourceName, {
          type: 'geojson',
          data: realMapInfo.realSource
        })
      if (realTampIndex >= 0 && realLayer) {
        // 若存在,删除
        maps.map.removeLayer('real_tamp')
        maps.LayerList.delete(realMapInfo.realLayerName)
      } else if ((realTampIndex >= 0 && !realLayer) || realLayer) {
        // 若不存在,增加
        if (realLayer) maps.map.removeLayer('real_tamp')
        maps.map.addLayer({
          id: realMapInfo.realLayerName,
          type: 'circle',
          source: realMapInfo.realSourceName,
          paint: {
            'circle-radius': {
              base: 2,
              stops: [
                [0, 0],
                [20, 20]
              ]
            },
            'circle-color': '#0000F0'
          }
        })
        maps.LayerList.add(realMapInfo.realLayerName)
      }
    }
    const clickMapEvent = (type: number) => {
      mapControl.tampPointInfo.show = false
      mapControl.tampPointInfo.type =
        mapControl.tampPointInfo.type == type ? -1 : type
    }
    function transWGS84ToLocal1(latitude: number, longitude: number){
      return new Promise((resolve, reject) => {
        axios
            .post('/common/transWGS84ToLocal', { lat: latitude, lng: longitude })
            .then((res: any) => {
              resolve(res)
            })
            .catch((err: any) => {
              reject(err)
            })
      })
    }
    // 84转ab
    const transWGS84ToLocal = (latitude: number, longitude: number) => {
      return new Promise((resolve, reject) => {
        axios
          .post('/common/transWGS84ToLocal', { lat: latitude, lng: longitude })
          .then((res: any) => {
            resolve(res)
          })
          .catch((err: any) => {
            reject(err)
          })
      })
    }
    // 获取点夯信息
    const getDotPoint = (latitude: number, longitude: number) => {
      return new Promise((resolve, reject) => {
        if (!inCellBaseInfo.value) {
          message.info('请先选择单元后再进行操作')
          return
        }
        let cellId = inCellBaseInfo.value.cellId
        let kind = mapControl.tampPointInfo.type
        axios
          .post('/tamp/findPointTimes', { cellId, kind, latitude, longitude })
          .then((res: any) => {
            resolve(res)
          })
          .catch((err: any) => {
            reject(err)
          })
      })
    }
    // 获取满夯信息
    const getFullPoint = (lat: number, lng: number) => {
      return new Promise((resolve, reject) => {
        if (!inCellBaseInfo.value) {
          message.info('请先选择单元后再进行操作')
          return
        }
        let cellID = inCellBaseInfo.value.cellId
        let workType = 11
        axios
          .post(
            '/qhMap/getWorkTimesbyCoord',
            qs.stringify({ cellID, workType, lat, lng }),
            { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
          )
          .then((res: any) => {
            resolve(res)
          })
          .catch((err: any) => {
            reject(err)
          })
      })
    }
    async function requestSomething(borderAry:any) {
      for (let i = 0; i < borderAry.length - 1; i++) {
        let pointAry = borderAry[i]
        await transWGS84ToLocal1(pointAry[1], pointAry[0]).then((res: any) => {
          if (res.data) {
            exAreaInfo.uploadFileRecord.border.first.push(res.data.x)
            exAreaInfo.uploadFileRecord.border.second.push(res.data.y)
            console.log("---------")
            console.log(i)
          } else {
            exAreaInfo.uploadFileRecord.border = {}
          }
        })
      }

    }
    // 保存绘制的区域
    const saveDrawArea = () => {
      exAreaInfo.showExModal = true
      removeDraw()
      // 0为 删除 2为第二个图形还没开始绘制
      if (drawData.features.length = 1) {
        // console.log(drawData)
        // exAreaInfo.uploadFileRecord.drawInfo = drawData
        exAreaInfo.uploadFileRecord.border.first = new Array()
        exAreaInfo.uploadFileRecord.border.second = new Array()
        let feature = drawData.features[0]
        let geometry = feature!.geometry
        let coordinates = geometry!.coordinates
        if (coordinates.length > 0) {
          let borderAry = coordinates[0]
          // console.log(borderAry.length)
          if (borderAry.length >= 1) {
            //调取
            requestSomething(borderAry)
            // for (let i = 0; i < borderAry.length - 1; i++) {
            //   let pointAry = borderAry[i]
            //   transWGS84ToLocal(pointAry[1], pointAry[0]).then((res: any) => {
            //     if (res.data) {
            //       exAreaInfo.uploadFileRecord.border.first.push(res.data.x)
            //       exAreaInfo.uploadFileRecord.border.second.push(res.data.y)
            //     } else {
            //       exAreaInfo.uploadFileRecord.border = {}
            //     }
            //   })
            // }
          }
        }
      }
    }
    // 打开排除区域弹框
    const openExAreaModal = (cellId: number) => {
      if (cellId <= 0) {
        message.info('请选择仓面后操作')
        return
      }
      removeDraw()
      axios.post('/common/findCellExcludeAreaByCellId', { cellId: cellId }).then((res: any) => {
        if (res.success) {
          exAreaInfo.exAreaList = res.data
          // console.log(JSON.stringify(res.data))
          exAreaInfo.showExModal = true
        } else {
          message.info('获取排除信息失败')
        }
      })
    }
    const removeDraw = () => {
      if (draw) {
        maps.map.removeControl(draw)
        draw = null
      }
      isDrawSave.value = false;
    }
    // 排除区域坐标点转换
    let pointArr:any = {
      border: {
        first: [],
        second: []
      }
    }
    // 排除区域坐标点转换
    async function requestSomeDrop(dropAry:any) {
      for (let i = 0; i < dropAry.first.length; i++) {
        // let dropArray = dropAry[i]
        await transWGS84ToLocal1(dropAry.second[i], dropAry.first[i]).then((res: any) => {
          if (res.data) {
            pointArr.border.first.push(res.data.x)
            pointArr.border.second.push(res.data.y)
            console.log("---------")
            console.log(i)
          } else {
            pointArr.border.first = new Array()
            pointArr.border.second = new Array()
          }
        })
      }
    }
    // 打开排除区域坐标弹窗
    const openCoordinateModel = (record:any) => {
      let pointList = new Array()
      coordinateList.borderList = new Array()
      pointArr.border.first = new Array()
      pointArr.border.second = new Array()

      // for (let i = 0; i < record.border.first.length; i++) {
      //   transWGS84ToLocal(record.border.second[i], record.border.first[i]).then((res: any) => {
      //     if (res.data) {
      //       pointArr.border.first.push(res.data.x)
      //       pointArr.border.second.push(res.data.y)
      //     } else {
      //       pointArr.border.first = new Array()
      //       pointArr.border.second = new Array()
      //     }
      //   })
      // }
      requestSomeDrop(record.border)
      setTimeout(()=>{
        for (let j = 0; j < pointArr.border.first.length; j++) {
          pointList.push({
            first: pointArr.border.first[j],
            second: pointArr.border.second[j],
          })
        }
        coordinateList.borderList = pointList
        showCoordinateModal.value = true
      },2000)
    }
    // 排除区域坐标点下载
    const downloadBorderFile = () =>{
      // 封装我们需要导出的数据信息
      let dataList:any = []
      // 这里处理的是Excel的表头，必须放在数据结构的第一个位置
      dataList.push(["P坐标", "H坐标"])
      coordinateList.borderList.forEach((item:any) => {
        dataList.push([item.first, item.second]);
      })
      TableToExcel(dataList, "排除区域坐标点.xlsx")
    }
    // 获取所有排除区域坐标点&序号
    const getAllPoint = (cellId: number) =>{
      clearSerial()
      axios.post('/common/findCellExcludeAreaByCellId', { cellId: cellId }).then((res: any) => {
        if (res.success) {
          exAreaSerial.data.features = new Array()
          let exAreaPointList:any = new Array()

          let maxFirstArr:any = [], minFirstArr:any =[], maxSecondArr:any = [], minSecondArr:any = []
          let maxFirst, minFirst,maxSecond,minSecond
          let firstArr:any = [], secondArr:any = []
          // 获取排除区域最大经纬度、最小经纬度
          for (let x = 0; x < res.data.length; x++) {
            maxFirst = res.data[x].border.first[0]
            minFirst = res.data[x].border.first[0]
            maxSecond = res.data[x].border.second[0]
            minSecond = res.data[x].border.second[0]
            for (let y = 0; y < res.data[x].border.first.length; y++) {
              if (res.data[x].border.first[y] > maxFirst) {
                maxFirst = res.data[x].border.first[y]
              }
              if (res.data[x].border.first[y] < minFirst) {
                minFirst = res.data[x].border.first[y]
              }
              if (res.data[x].border.second[y] > maxSecond) {
                maxSecond = res.data[x].border.second[y]
              }
              if (res.data[x].border.second[y] < minSecond) {
                minSecond = res.data[x].border.second[y]
              }
            }
            maxFirstArr.push(maxFirst)
            minFirstArr.push(minFirst)
            maxSecondArr.push(maxSecond)
            minSecondArr.push(minSecond)
          }

          // 取中间值
          for (let i = 0; i < maxFirstArr.length; i++) {
            firstArr.push((maxFirstArr[i] + minFirstArr[i])/2)
            secondArr.push((maxSecondArr[i] + minSecondArr[i])/2)
          }

          for (let j = 0; j < res.data.length; j++) {
            exAreaPointList.push({
              first: firstArr[j],
              second: secondArr[j],
              serial: res.data[j].serial
            })
          }

          exAreaPointList.forEach((item:any) => {
            exAreaSerial.data.features.push({
              type: "Feature",
              geometry: {
                type: "Point",
                coordinates: [item.first, item.second]
              },
              properties: {
                'size': 0.1,
                'rotate': 0,
                'color': 'red',
                'serial': item.serial
              }
            })
          })
          addSerialLayer()
        } else {
          message.info('获取排除信息失败')
        }
      })
    }
    // 清除排除区域序号图层
    const clearSerial = () =>{
      if (maps.map.getLayer('pointLayer')) {
        maps.map.removeLayer('pointLayer')
      }
      if (maps.map.getLayer('testLayer')) {
        maps.map.removeLayer('testLayer')
      }
      if (maps.map.getSource('testSource')) {
        maps.map.removeSource('testSource')
      }
    }
    // 添加排除区域序号图层
    const addSerialLayer = () =>{
      clearSerial()
      maps.map.addSource('testSource', {type: 'geojson', data: exAreaSerial.data})
      maps.map.addLayer({
        id: 'pointLayer',
        type: 'circle',
        source: 'testSource',
        paint: {
          'circle-radius': 12,
          'circle-color': '#19A160 '
        }
      })
      maps.map.addLayer({
        id: 'testLayer',
        type: "symbol",
        // source: {
        //   type: 'geojson',
        //   data: exAreaSerial.data
        // },
        source: 'testSource',
        filter: ['!', ['has', 'point_count']],
        layout: {
          'icon-image': '',
          'visibility': 'visible',
          'text-field': '{serial}',//此属性为需要显示的字段
          'text-font': [ "DIN Offc Pro Medium", "Arial Unicode MS Bold"],
          'text-size': 15,
          'text-offset': [0, 0],
          'text-allow-overlap': true, // 是否允许文本重叠（可选，默认值为 false。
          'text-anchor': 'top',
        },
        paint: {
          // 绘制类属性
          // 文本类属性（需要设置 text-field）样式才生效
          'text-color': '#fff', // 文本的颜色
          'text-translate': [-1, -9], // 文本的平移（可选，通过平移 [x, y] 达到一定的偏移量。默认值为 [0, 0]
          'text-translate-anchor': 'map', // 文本的平移锚点，即相对的参考物（可选，可选值为 map、viewport，默认为 map）
        }
      })
    }
    //打开三检弹窗
    const openTpiModal = (cellId: number) => {
      if (cellId <= 0) {
        message.info('请选择仓面后操作')
        return
      }
      mapControl.tampPointInfo.type = -1
      mapControl.tampPointInfo.show = false
      tpiListInfo.value.showModal = true
      TpiModalInit.value.setCellId(cellId)
    }
    // 重新绘制边界
    const createTiledMap = (cellId: number) => {
      return new Promise((resolve, reject) => {
        axios
          .post(
            '/qhMap/reCreatBorder',
            qs.stringify({
              cellID: cellId,
              workType: 1
            }),
            {
              headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
            }
          )
          .then((res: any) => {
            resolve(res.success)
          })
      })
    }
    //绘制排除区域
    const drawTheBorder = (record: any) => {
      exAreaInfo.uploadFileRecord = record
      exAreaInfo.showExModal = false
      isDrawSave.value = true;
      initDraw()
    }
    // 增加一列新的排除区域
    const addExArea = () => {
      exAreaInfo.exAreaList.push({
        cellId: inCellBaseInfo.value.cellId,
        excludedId: -1,
        excludedName: null,
        reason: null,
        userName: userName.value,
        border: { first: new Array(), second: new Array() },
        gtmCreateTime: moment().format('yyyy-MM-DD HH:mm:ss')
      })
    }
    // 保存排除区域
    const saveExArea = (record: any) => {
      if (
        lodash.isEmpty(record.excludedName) ||
        lodash.trim(record.excludedName).length == 0
      ) {
        message.info('请输入排除区域名称')
        return
      }
      if (record.border.first.length == 0) {
        message.info('请录入排除区域边界')
        return
      }
      axios
        .post('/common/saveCellExcludeAreaByCellIdAB', {
          cellId: record.cellId,
          excludedId: record.excludedId,
          reason: record.reason,
          excludedName: record.excludedName,
          border: record.border
        })
        .then((res: any) => {
          if (res.success) {
            record.excludedId = res.data.excludedId
            createTiledMap(record.cellId)
            message.info('保存成功')
          } else {
            message.info(res.msg)
          }
        })
    }
    // 删除排除区域
    const delExArea = (record: any, index: number) => {
      if (record.excludedId > 0) {
        axios
          .post('/common/deleteCellExcludeAreaByCellId', {
            cellId: inCellBaseInfo.value.cellId,
            excludedId: record.excludedId
          })
          .then((res: any) => {
            if (res.success) {
              exAreaInfo.exAreaList.splice(index, 1)
              createTiledMap(inCellBaseInfo.value.cellId)
              removeDraw()
              message.info('删除成功')
            } else {
              message.info(res.msg)
            }
          })
      } else {
        exAreaInfo.exAreaList.splice(index, 1)
        createTiledMap(inCellBaseInfo.value.cellId)
        removeDraw()
        message.info('删除成功')
      }
    }
    // 打开文件选择框
    const openFileModal = (record: any) => {
      exAreaInfo.uploadFileRecord = record
      document.getElementById('read-ex-area-input')?.click()
    }
    // 读取边界数据
    const readBorderFile = () => {
      let inputDOM: any = document.getElementById('read-ex-area-input')
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader()
        reader.readAsText(files[0], 'UTF-8')
        reader.onload = (e: any) => {
          try {
            let fileStr = e.target.result
            let fileStrArr = fileStr.split(',,')
            exAreaInfo.uploadFileRecord.border.first = new Array()
            exAreaInfo.uploadFileRecord.border.second = new Array()

            for (let i = 0; i < fileStrArr.length; i++) {
              let pointArr = fileStrArr[i].split(',')
              if (pointArr.length == 2) {
                exAreaInfo.uploadFileRecord.border.first.push(
                  parseFloat(pointArr[0])
                )
                exAreaInfo.uploadFileRecord.border.second.push(
                  parseFloat(pointArr[1])
                )
              }
            }
            console.log(JSON.stringify(exAreaInfo.uploadFileRecord))
          } catch (e) {
            message.warn('导入格式错误' + e)
            console.log(e)
          }
        }
        inputDOM.value = ''
      }
    }

    // 看板跳转
    const getQueryVariable=(variable:any)=>{
      // var query = window.location.search;
      var query = window.location.hash.split("?")[1];
      // if(query.indexOf('?') === -1) return null; //如果url中没有传参直接返回空
      //key存在先通过search取值如果取不到就通过hash来取
      if (query != undefined) {
        // query = query.substr(1) || window.location.hash.split("?")[1];
        var vars = query.split("&");
        for (var i = 0;i < vars.length;i++) {
          var pair = vars[i].split("=");
          if(pair[0] == variable){return pair[1];}
        }
      }
      return null
    }
    const getParameters = () =>{
      let id:any = getQueryVariable('id')
      let type:any = getQueryVariable('type')
      if (id != null && type != null) {
        zoneId.value = parseInt(id)
        zoneKind.value = parseInt(type)
      }
    }

    onMounted(() => {
      if (sections.value.length > 0) {
        cellQueryFormState.value.sections[0].sectionId =
          sections.value[0].sectionId
        getCellBaseInfoList(null).then(() => {
          // 看板跳转
          getParameters()
          if (zoneId.value != null || zoneKind.value != null) {
            let cell = {
              cellId: zoneId.value,
              kind: zoneKind.value
            }
            removeDraw()
            clearSerial()
            let f1 = getCellBaseInfo(cell)
            let f2 = getCellWorkMachineryByCellId(cell)
            Promise.all([f1, f2]).then((res: any) => {
              // 1.持久化数据
              // 清除旧图层&数据源
              maps.LayerList.forEach((item: any) => {
                if (maps.map.getLayer(item)) {
                  maps.map.removeLayer(item)
                  maps.LayerList.delete(item)
                }
              })
              maps.sourceList.forEach((item: any) => {
                if (maps.map.getSource(item)) maps.map.removeSource(item)
              })
              // 添加默认图层
              let layerInfo: MapLayerRequestInfo = {
                cellId: inCellBaseInfo.value.cellId,
                craft: 'HaErBin-QH',
                type: 'border'
              }
              addSource(layerInfo)
              addLayer(layerInfo)

              // 2.实时数据
              // 先清除旧的实时显示相关的数据,图层,marker
              realMapInfo.deviceList.forEach((item: any) => {
                item.deviceMarker.remove()
              })
              realMapInfo.deviceList = new Array<MapDeviceInfo>()
              MqttService.unsubscribe(realMapInfo.subscribeList)
              realMapInfo.subscribeList = new Array<string>()
              realMapInfo.realSource.features = new Array<any>()
              if (maps.map.getLayer(realMapInfo.realLayerName))
                maps.map.removeLayer(realMapInfo.realLayerName)
              if (maps.map.getSource(realMapInfo.realSourceName))
                maps.map.removeSource(realMapInfo.realSourceName)

              // 订阅新选定仓面的设备数据
              workListInfo.value.workList = res[1].data
              res[1].data.forEach((item: any) => {
                let el = document.createElement('div')
                el.className = 'device-tamp'
                el.innerText = `${item.deviceName}`

                realMapInfo.deviceList.push({
                  deviceId: item.deviceId,
                  deviceInfo: item,
                  deviceMarker: new mapboxgl.Marker(el)
                      .setLngLat([0, 0])
                      .setOffset(new mapboxgl.Point(86, -16))
                      .addTo(maps.map)
                })
                MqttService.subscribe(
                    `${config.craft.tamp.mqtt.topic}${item.deviceSn}`
                )
              })

              // 3.操作界面
              mapControl.baseControl = ['border', 'real_tamp']
              // 跳转位置
              if (res[0].data.centLat && res[0].data.centLon) {
                maps.map.setZoom(17)
                let cellCenter = new mapboxgl.LngLat(
                    res[0].data.centLon,
                    res[0].data.centLat
                )
                mapToCell(cellCenter)
              }
            })
            // 新三检
            getAreaStatus(cell.cellId)
            getAllPoint(cell.cellId)
          }
        })
      }
      // 加载地图
      initMap()
      // 初始化mqtt
      MqttService.init(
        `${config.craft.tamp.mqtt.ip}`,
        new MqttOptions(
          `${config.craft.tamp.mqtt.userName}`,
          `${config.craft.tamp.mqtt.password}`
        ),
        (topic: any, msg: any) => {
          /**
           * 车辆图层
           * 先判断当前车辆在数据源中的位置
           * 若不存在车辆,则新增
           * 若存在,则修改当前记录
           */
          msg = JSON.parse(msg.toString())
          let deviceListIndex = realMapInfo.deviceList.findIndex(
            (item: any) => {
              return item.deviceId == msg.deviceId
            }
          )
          if (deviceListIndex < 0) return

          realMapInfo.deviceList[
            deviceListIndex
          ].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.timesBuild}击`
          realMapInfo.deviceList[deviceListIndex].deviceMarker.setLngLat([
            msg.longitude,
            msg.latitude
          ])

          realMapInfo.realSource.features.push({
            type: 'Feature',
            geometry: {
              type: 'Point',
              coordinates: [msg.longitude, msg.latitude]
            }
          })
          if (maps.map.getLayer(realMapInfo.realLayerName))
            maps.map.removeLayer(realMapInfo.realLayerName)
          if (maps.map.getSource(realMapInfo.realSourceName))
            maps.map.removeSource(realMapInfo.realSourceName)

          maps.map.addSource(realMapInfo.realSourceName, {
            type: 'geojson',
            data: realMapInfo.realSource
          })
          maps.map.addLayer({
            id: realMapInfo.realLayerName,
            type: 'circle',
            source: realMapInfo.realSourceName,
            paint: {
              'circle-radius': {
                base: 2,
                stops: [
                  [0, 0],
                  [20, 20]
                ]
              },
              'circle-color': '#0000F0'
            }
          })
          maps.LayerList.add(realMapInfo.realLayerName)
        }
      )
    })

    onBeforeUnmount(() => {
      // 关闭mqtt
      MqttService.unsubscribe(realMapInfo.subscribeList)
      MqttService.end()
      // 移除地图
      maps.map.remove()
    })

    return {
      sections,
      setHeight,
      kindDict,
      cellStatusDict,
      handleCell,
      ...toRefs(mapControl),
      clickMapControl,
      clickMapEvent,
      workListInfo,
      deviceTypeDict,

      cellQueryFormRef,
      cellQueryFormState,
      cellBaseInfoList,
      inCellBaseInfo,
      getCellBaseInfoList,
      setCellStatus,

      ...toRefs(exAreaInfo),
      ...toRefs(coordinateList),
      showCoordinateModal,
      ...toRefs(exAreaSerial),
      openExAreaModal,
      openCoordinateModel,
      downloadBorderFile,
      addExArea,
      saveExArea,
      delExArea,
      saveDrawArea,
      openFileModal,
      readBorderFile,
      drawTheBorder,
      //三检
      openTpiModal,
      tpiListInfo,
      TpiModalInit,
      tpiStatue,

      isDrawSave,
      addSerialLayer,

      // 看板跳转
      zoneId,
      zoneKind,
      getParameters
    }
  },
  components: {
    EditOutlined,
    SaveOutlined,
    DeleteOutlined,
    CloseOutlined,
    CheckOutlined,
    BorderOuterOutlined,
    SModal,
    //三检
    tpiModal
  }
})
</script>

<style lang="scss" scoped>
.monitor-box {
  display: flex;
  width: 100%;
  height: 100%;
  .left-box {
    display: flex;
    flex-direction: column;
    width: 495px;
    height: 100%;
    .control-box {
      display: flex;
      width: 100%;
      height: 262px;
      .search-box {
        width: 235px;
        height: 100%;
        padding: 12px 17px;
        box-sizing: border-box;
        ::v-deep label {
          color: #666666;
        }
        ::v-deep .ant-form-item {
          display: flex;
          margin-bottom: 10px;
        }
        ::v-deep .ant-form-item-control-wrapper {
          flex: 1;
        }
        ::v-deep .ant-select {
          width: 100%;
        }
      }
      .map-control {
        width: 240px;
        height: 100%;
        margin-left: 20px;
        padding: 10px 17px;
        box-sizing: border-box;
        .map-control-title {
          color: #333333;
          font-weight: bold;
        }
        .map-control-title:nth-of-type(n + 2) {
          display: inline-block;
          margin-top: 16px;
        }
        ::v-deep .ant-checkbox-group {
          .ant-checkbox-wrapper {
            width: 100px;
            margin-right: 0px;
            border: 2px solid #1890ff;
            box-sizing: border-box;
            border-radius: 2px;
            color: #1890ff;
            font-size: 12px;
            margin-top: 8px;
            padding: 2px 2px;
            box-sizing: border-box;
            > span:nth-of-type(n + 1) {
              padding-left: 4px;
              padding-right: 4px;
            }
          }
          .ant-checkbox-wrapper:nth-child(odd) {
            margin-right: 6px;
          }
          .ant-checkbox-inner {
            border: 1px solid #1890ff;
          }
        }
      }
    }
    .cell-table-box {
      display: flex;
      flex-direction: column;
      width: 495px;
      flex: 1;
      margin-top: 20px;
      padding: 0 13px;
      .table-box-header {
        color: #333333;
        font-size: 18px;
        font-weight: bold;
        padding: 18px 0 10px 10px;
      }
      .table-box-center {
        width: 100%;
        flex: 1;
      }
      ::v-deep .table-icon-box {
        display: flex;
        justify-content: space-around;
        > div:hover {
          color: #1677ff;
        }
      }
    }
  }
  .right-box {
    display: flex;
    flex-direction: column;
    flex: 1;
    height: 100%;
    margin-left: 20px;
    .base-info-box {
      width: 100%;
      height: 82px;
      padding: 14px 0 0px;
    }
    .map-box {
      position: relative;
      flex: 1;
      width: 100%;
      height: 100%;
      margin-top: 20px;
      box-sizing: border-box;
      .point-info {
        z-index: 1;
        .point-header {
          display: flex;
          width: 100%;
          height: 34px;
          line-height: 34px;
          padding: 0 16px;
          box-sizing: border-box;
          justify-content: space-between;
          border-bottom: 1px solid #eeeeee;
          > span {
            font-weight: bold;
          }
          ::v-deep .anticon {
            line-height: 34px;
          }
        }
      }
      .point-info-1 {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 40px;
        right: 5px;
        width: 520px;
        height: 315px;
        background: #ffffff;
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
        border-radius: 2px;
        box-sizing: border-box;
        .point-content {
          display: flex;
          width: 100%;
          flex: 1;
          .left {
            display: flex;
            flex-direction: column;
            width: 240px;
            height: 100%;
            padding: 0 10px;
            justify-content: center;
            box-sizing: border-box;
            .left-info-box {
              padding: 5px 16px;
              box-sizing: border-box;
              background-color: #f9f9f9;
              ::v-deep .ant-row {
                line-height: 37px;
                .ant-col:first-child {
                  color: #666666;
                  font-weight: bold;
                }
                .ant-col:last-child {
                  color: #666666;
                  text-align: right;
                }
              }
            }
          }
          .right {
            width: 280px;
            height: 100%;
          }
        }
      }
      .point-info-2 {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 40px;
        right: 5px;
        width: 220px;
        background: #ffffff;
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
        border-radius: 2px;
        box-sizing: border-box;
        .point-content {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          padding: 0 16px;
          .info {
            width: 100%;
            ::v-deep .ant-row {
              line-height: 37px;
              .ant-col:first-child {
                color: #666666;
                font-weight: bold;
              }
              .ant-col:last-child {
                color: #666666;
                text-align: right;
              }
            }
          }
        }
      }
      .map-event-control {
        display: flex;
        position: absolute;
        top: 5px;
        right: 5px;
        height: 30px;
        background-color: #ffffff;
        border-radius: 3px;
        z-index: 10;
        overflow: hidden;
        .map-control-button {
          width: 90px;
          height: 30px;
          font-size: 14px;
          line-height: 28px;
          text-align: center;
          border: 1px solid #f0f0f0;
          box-sizing: border-box;
          cursor: pointer;
        }
        .map-control-active {
          color: #1890ff;
        }
        .map-control-disable {
          color: #8d8d8d;
        }
      }
      #mapboxgl-box {
        display: flex;
        width: 100%;
        height: calc(100% - 6px);
        box-sizing: border-box;
      }
      .tamp-legend {
        position: absolute;
        display: flex;
        flex-direction: column;
        padding: 8px 2.5px;
        width: 84px;
        height: 100px;
        right: 5px;
        bottom: 12px;
        background: #ffffff;
        border-radius: 3px;
        box-sizing: border-box;
        z-index: 1;
        > div {
          display: flex;
          width: 100%;
          height: 28px;
          .legend {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 28px;
            height: 28px;
            > div {
              width: 12px;
              height: 12px;
              border-radius: 50%;
            }
          }
          .legend-title {
            color: #666666;
            line-height: 28px;
            text-align: center;
          }
        }
      }
      .ex-area-btn {
        position: absolute;
        left: 5px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/ex_area.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
      .work-list-btn {
        position: absolute;
        left: 42px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/work_list.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
      // 三检
      .tpi-list-btn {
        position: absolute;
        left: 79px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/tpi_list.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
    }
  }
}
.smodal-box {
  box-sizing: border-box;
}
.smodal-to-cell {
  width: 100%;
  height: 100%;
}
.ex-area-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .ex-table-box {
    flex: 1;
    padding-top: 10px;
  }
  .ex-area-btn-box {
    display: flex;
    justify-content: flex-end;
    width: 100%;
    height: 48px;
  }
}
.coor-table-box {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .down-btn-box {
    display: flex;
    justify-content: flex-end;
    width: 100%;
    height: 48px;
    margin-top: 20px;
  }
}

::v-deep .mapboxgl-control-container {
  display: block;

  .mapboxgl-ctrl-bottom-left {
    display: none;
  }
}
::v-deep .mapboxgl-ctrl {
  display: block !important;
}
.draw-save {
  position: absolute;
  top: 80px;
  left: 10px;
  text-align: center;
}
</style>

